package com.tangzx.tasks

import com.tangzx.SWFConfusionPluginConvention
import com.tangzx.SWFInput
import com.tangzx.data.Swf
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
import com.tangzx.builder.DefaultMixWordFactory
import com.tangzx.builder.MovieMixer
import com.tangzx.builder.abc.string.StringVo
import com.tangzx.builder.context.AbcContext
import com.tangzx.builder.decoder.ExcludeLib

/**
 * Created by Tangzx on 2015/6/23.
 */
class ConfusionTask extends DefaultTask {
    // 排除的关键字列表
    private String keyWordList;
    // 混淆关键字
    private File mixCharFile;
    private File logFile;
    private FileOutputStream logStream;

    private DefaultMixWordFactory mixWordFactory = new DefaultMixWordFactory() {
        @Override
        public void log(String ori, String mix) {
            logMix(ori, mix);
        }
    };

    private ArrayList<Swf> allExcludeLibList = new ArrayList<Swf>();
    private ArrayList<Swf> allSwf = new ArrayList<Swf>();
    private AbcContext abcContext = new AbcContext();

    @TaskAction
    def exec() {
        SWFConfusionPluginConvention cp = project["confusion"] as SWFConfusionPluginConvention

        this.abcContext.setMixWordFactory(this.mixWordFactory)
        this.logFile = cp.logFile
        this.mixCharFile = cp.mixWord
        this.keyWordList = cp.keyWord

        for (SWFInput s : cp.allSwf) {
            Swf swf = new Swf()
            swf.input = s.input
            swf.output = s.output
            allSwf.add(swf)
        }

        for (SWFInput s : cp.allExcludeLibList) {
            Swf swf = new Swf()
            swf.input = s.input
            swf.output = s.output
            allExcludeLibList.add(swf)
        }

        try {
            if (logFile != null) {
                if (!logFile.exists())
                    logFile.createNewFile();
                logStream = new FileOutputStream(logFile);
            }

            configKeyWordList();
            configMixChar();
            configExcludeLib();
            MovieMixer[] mm = new MovieMixer[allSwf.size()];
            //解析
            for (int i = 0; i < mm.length; i++) {
                Swf swf = allSwf.get(i);
                MovieMixer mixer = new MovieMixer(abcContext,
                        new FileInputStream(swf.getInput()));
                mixer.parse();
                mm[i] = mixer;
            }
            //混淆
            for (int i = 0; i < mm.length; i++) {
                MovieMixer movieMixer = mm[i];
                movieMixer.mix();
            }
            //重组输出
            for (int i = 0; i < mm.length; i++) {
                Swf swf = allSwf.get(i);
                MovieMixer movieMixer = mm[i];
                movieMixer.writeTo(new FileOutputStream(swf.getOutput()));
            }

            if (logStream != null) {
                logStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 将混淆的日志打出
     * @param ori
     * @param mix
     */
    private void logMix(String ori, String mix) {
        if (logStream != null) {
            String s = ori + "<<-->>" + mix + "\n";
            try {
                logStream.write(s.getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void configExcludeLib() throws Exception {
        for (Swf swf : allExcludeLibList) {
            ExcludeLib el = new ExcludeLib(new FileInputStream(swf.getInput()));
            el.parse();
            abcContext.merge(el.getAbcContext());
        }
    }

    private void configKeyWordList() throws Exception {
        if (keyWordList != null) {
            BufferedReader br = new BufferedReader(new FileReader(keyWordList));
            String s;
            while ((s = br.readLine()) != null) {
                if (!s.startsWith("//")) {
                    StringVo vo = abcContext.getString(s).vo;
                    vo.setCanNotMix();
                    vo.pushString(true);
                }
            }
        }
    }

    private void configMixChar() throws Exception {
        if (mixCharFile != null) {
            ArrayList<String> list = new ArrayList<String>();
            BufferedReader br = new BufferedReader(new FileReader(mixCharFile));
            String s;
            while ((s = br.readLine()) != null) {
                if (list.indexOf(s) == -1)
                    list.add(s);
            }
            mixWordFactory.setList(list.toArray(new String[list.size()]));
            abcContext.setMixWordFactory(mixWordFactory);
        }
    }
}
